<!DOCTYPE html>
<html lang="en" data-bs-theme="auto">

<head>
  <%- header %>
  <link rel="stylesheet" href="./styles/apps.css" />
</head>

<body id="app" v-cloak>
  <Navbar></Navbar>
  <div class="container-fluid px-4">
    <div class="my-4">
      <h1 class="page-title">{{ $t('apps.applications_title') }}</h1>
      <p class="page-subtitle">{{ $t('apps.applications_desc') }}</p>
    </div>
    
    <!-- 搜索栏和功能按钮 -->
    <div class="search-container mb-4">
      <div class="search-box">
        <i class="fas fa-search search-icon"></i>
        <input 
          type="text" 
          class="form-control search-input" 
          :placeholder="$t('apps.search_placeholder')"
          v-model="searchQuery"
          @input="debouncedSearch"
        >
        <button v-if="searchQuery" class="btn-clear-search" @click="clearSearch">
          <i class="fas fa-times"></i>
        </button>
      </div>
      
      <!-- 功能按钮组 -->
      <div class="action-buttons">
        <button 
          class="cute-btn cute-btn-primary" 
          @click="newApp"
          :title="$t('apps.add_new')"
        >
          <i class="fas fa-plus"></i>
        </button>
        <button 
          class="cute-btn cute-btn-secondary" 
          data-bs-toggle="modal" 
          data-bs-target="#envVarsModal"
          :title="'环境变量说明'"
        >
          <i class="fas fa-info-circle"></i>
        </button>
        <button 
          class="cute-btn cute-btn-success" 
          @click="save"
          :title="$t('_common.save')"
        >
          <i class="fas fa-save"></i>
        </button>
      </div>
    </div>
    
    <!-- 应用卡片列表 -->
    <div class="apps-grid-container">
      <draggable 
        v-if="!searchQuery" 
        v-model="apps" 
        item-key="name"
        class="apps-grid"
        :animation="300"
        :delay="0"
        :disabled="false"
        ghost-class="app-card-ghost"
        chosen-class="app-card-chosen"
        drag-class="app-card-drag"
        @start="onDragStart"
        @end="onDragEnd"
      >
        <template #item="{element: app, index}">
          <app-card 
            :app="app"
            :draggable="true"
            :is-drag-result="false"
            :is-dragging="isDragging"
            @edit="editApp(index)"
            @delete="showDeleteForm(index)"
            @copy-success="handleCopySuccess"
            @copy-error="handleCopyError"
          ></app-card>
        </template>
      </draggable>
      
      <!-- 搜索结果视图（不可拖拽） -->
      <div v-else class="apps-grid">
        <app-card 
          v-for="(app, index) in filteredApps" 
          :key="'search-' + index"
          :app="app"
          :draggable="false"
          :is-search-result="true"
          :is-dragging="false"
          @edit="editApp(getOriginalIndex(app, index))"
          @delete="showDeleteForm(getOriginalIndex(app, index))"
          @copy-success="handleCopySuccess"
          @copy-error="handleCopyError"
        ></app-card>
      </div>
      
      <!-- 空状态 -->
      <div v-if="(searchQuery && filteredApps.length === 0) || (!searchQuery && apps.length === 0)" class="empty-state">
        <div class="empty-icon">
          <i class="fas fa-rocket"></i>
        </div>
        <h3 class="empty-title">
          {{ searchQuery ? '未找到匹配的应用' : '暂无应用' }}
        </h3>
        <p class="empty-subtitle">
          {{ searchQuery ? '尝试使用不同的搜索关键词' : '点击下方按钮添加第一个应用' }}
        </p>
        <button v-if="!searchQuery" class="btn btn-primary" @click="newApp">
          <i class="fas fa-plus me-1"></i>{{ $t('apps.add_new') }}
        </button>
      </div>
    </div>


    
    <!-- 应用编辑器 -->
    <app-editor 
      v-if="editingApp"
      :app="editingApp" 
      :platform="platform"
      :disabled="isSaving"
      @save-app="handleSaveApp"
      @close="closeAppEditor"
    ></app-editor>

    <!-- 提示消息 -->
    <div v-if="message" class="alert-toast" :class="messageClass">
      <i class="fas" :class="getMessageIcon()"></i>
      <span>{{ message }}</span>
      <button class="btn-close-toast" @click="message = ''">
        <i class="fas fa-times"></i>
      </button>
    </div>

    <!-- 环境变量说明模态框 -->
    <div class="modal fade" id="envVarsModal" tabindex="-1">
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="envVarsModalLabel">
              <i class="fas fa-info-circle me-2"></i>{{ $t('apps.env_vars_about') }}
            </h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <div class="alert alert-info">
              <div class="form-text">
                <h6>{{ $t('apps.env_vars_about') }}</h6>
                {{ $t('apps.env_vars_desc') }}
              </div>
            </div>
            <div class="env-vars-table">
              <div class="table-responsive">
                <table class="table">
                  <thead>
                    <tr>
                      <th><strong>{{ $t('apps.env_var_name') }}</strong></th>
                      <th><strong>说明</strong></th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="(desc, varName) in envVars" :key="varName">
                      <td><code class="env-var-name">{{ varName }}</code></td>
                      <td>{{ desc }}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            <div class="mt-3">
              <div class="form-text" v-if="platform === 'windows'">
                <strong>{{ $t('apps.env_qres_example') }}</strong>
                <pre class="code-example">cmd /C &lt;{{ $t('apps.env_qres_path') }}&gt;\QRes.exe /X:%SUNSHINE_CLIENT_WIDTH% /Y:%SUNSHINE_CLIENT_HEIGHT% /R:%SUNSHINE_CLIENT_FPS%</pre>
              </div>
              <div class="form-text" v-else-if="platform === 'linux'">
                <strong>{{ $t('apps.env_xrandr_example') }}</strong>
                <pre class="code-example">sh -c "xrandr --output HDMI-1 --mode \"${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}\" --rate ${SUNSHINE_CLIENT_FPS}"</pre>
              </div>
              <div class="form-text" v-else-if="platform === 'macos'">
                <strong>{{ $t('apps.env_displayplacer_example') }}</strong>
                <pre class="code-example">sh -c "displayplacer "id:&lt;screenId&gt; res:${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT} hz:${SUNSHINE_CLIENT_FPS} scaling:on origin:(0,0) degree:0""</pre>
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <a href="https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/guides/app_examples.html" 
                target="_blank" class="btn btn-outline-primary">
              <i class="fas fa-external-link-alt me-1"></i>{{ $t('_common.see_more') }}
            </a>
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
              <i class="fas fa-times me-1"></i>关闭
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
<script type="module">
  import { createApp } from 'vue';
  import { initApp } from './init';
  import Navbar from './Navbar.vue';
  import AppEditor from './components/AppEditor.vue';
  import AppCard from './components/AppCard.vue';
  import { Modal } from 'bootstrap';
  import draggable from 'vuedraggable';
  import { AppService } from './services/appService.js';
  import { APP_CONSTANTS, ENV_VARS_CONFIG } from './utils/constants.js';
  import { debounce, deepClone } from './utils/helpers.js';

  const app = createApp({
    components: {
      Navbar,
      AppEditor,
      AppCard,
      draggable,
    },
    data() {
      return {
        apps: [],
        filteredApps: [],
        searchQuery: '',
        editingApp: null,
        platform: "",
        envVarsModal: null,
        message: '',
        messageType: 'success',
        isSaving: false,
        isDragging: false,
        envVars: {},
        debouncedSearch: null
      };
    },
    computed: {
      messageClass() {
        return {
          'alert-success': this.messageType === 'success',
          'alert-error': this.messageType === 'error',
          'alert-warning': this.messageType === 'warning',
          'alert-info': this.messageType === 'info'
        };
      }
    },
    async mounted() {
      // 初始化环境变量
      this.initEnvVars();
      
      // 初始化防抖搜索
      this.debouncedSearch = debounce(this.performSearch, APP_CONSTANTS.SEARCH_DEBOUNCE_TIME);
      
      // 初始化环境变量模态框
      try {
        this.envVarsModal = new Modal(document.getElementById('envVarsModal'));
      } catch (error) {
        console.warn('Environment variables modal initialization failed:', error);
      }
      
      // 加载数据
      await this.loadApps();
      await this.loadPlatform();
    },
    methods: {
      // ======================
      // 生命周期和初始化方法
      // ======================
      
      /**
       * 初始化环境变量
       */
      initEnvVars() {
        this.envVars = {};
        for (const [key, translationKey] of Object.entries(ENV_VARS_CONFIG)) {
          this.envVars[key] = this.$t(translationKey);
        }
      },
      
      // ======================
      // 数据加载方法
      // ======================
      
      /**
       * 加载应用列表
       */
      async loadApps() {
        try {
          this.apps = await AppService.getApps();
          this.filteredApps = [...this.apps];
        } catch (error) {
          console.error('加载应用失败:', error);
          this.showMessage('加载应用失败', APP_CONSTANTS.MESSAGE_TYPES.ERROR);
        }
      },
      
      /**
       * 加载平台信息
       */
      async loadPlatform() {
        try {
          this.platform = await AppService.getPlatform();
        } catch (error) {
          console.error('加载平台信息失败:', error);
          this.platform = APP_CONSTANTS.PLATFORMS.WINDOWS; // 默认平台
        }
      },
      
      // ======================
      // 搜索相关方法
      // ======================
      
      /**
       * 执行搜索
       */
      performSearch() {
        this.filteredApps = AppService.searchApps(this.apps, this.searchQuery);
      },
      
      /**
       * 清除搜索
       */
      clearSearch() {
        this.searchQuery = '';
        this.performSearch();
      },
      
      /**
       * 获取原始索引
       */
      getOriginalIndex(app, filteredIndex) {
        return this.apps.findIndex(a => a === app);
      },
      
      // ======================
      // 应用管理方法
      // ======================
      
      /**
       * 新增应用
       */
      newApp() {
        this.editingApp = {
          ...APP_CONSTANTS.DEFAULT_APP,
          index: -1
        };
      },
      
      /**
       * 编辑应用
       */
      editApp(index) {
        this.editingApp = deepClone(this.apps[index]);
        this.editingApp.index = index;
      },
      
      /**
       * 关闭应用编辑器
       */
      closeAppEditor() {
        this.editingApp = null;
      },
      
      /**
       * 处理保存应用
       */
      async handleSaveApp(appData) {
        try {
          await AppService.saveApps(this.apps, appData);
          await this.loadApps();
          this.editingApp = null;
          this.showMessage('应用保存成功', APP_CONSTANTS.MESSAGE_TYPES.SUCCESS);
        } catch (error) {
          console.error('保存应用失败:', error);
          this.showMessage('保存应用失败', APP_CONSTANTS.MESSAGE_TYPES.ERROR);
        }
      },
      
      /**
       * 显示删除确认
       */
      showDeleteForm(index) {
        const confirmed = confirm(
          `确定要删除应用 "${this.apps[index].name}" 吗？`
        );
        
        if (confirmed) {
          this.deleteApp(index);
        }
      },
      
      /**
       * 删除应用
       */
      async deleteApp(index) {
        try {
          await AppService.deleteApp(index);
          this.apps.splice(index, 1);
          this.performSearch(); // 重新搜索
          this.showMessage('应用删除成功', APP_CONSTANTS.MESSAGE_TYPES.SUCCESS);
        } catch (error) {
          console.error('删除应用失败:', error);
          this.showMessage('删除应用失败', APP_CONSTANTS.MESSAGE_TYPES.ERROR);
        }
      },
      
      /**
       * 保存应用列表
       */
      async save() {
        this.isSaving = true;
        try {
          await AppService.saveApps(this.apps, null);
          this.showMessage('保存成功！', APP_CONSTANTS.MESSAGE_TYPES.SUCCESS);
        } catch (error) {
          console.error('保存失败:', error);
          this.showMessage('保存失败', APP_CONSTANTS.MESSAGE_TYPES.ERROR);
        }
        this.isSaving = false;
      },
      
      // ======================
      // 消息处理方法
      // ======================
      
      /**
       * 显示消息
       */
      showMessage(message, type = APP_CONSTANTS.MESSAGE_TYPES.INFO) {
        this.message = message;
        this.messageType = type;
        
        // 自动隐藏消息
        setTimeout(() => {
          this.message = '';
        }, APP_CONSTANTS.MESSAGE_AUTO_HIDE_TIME);
      },
      
      /**
       * 获取消息图标
       */
      getMessageIcon() {
        return APP_CONSTANTS.MESSAGE_ICONS[this.messageType] || APP_CONSTANTS.MESSAGE_ICONS.info;
      },
      
      /**
       * 处理复制成功
       */
      handleCopySuccess(message) {
        this.showMessage(message, APP_CONSTANTS.MESSAGE_TYPES.SUCCESS);
      },
      
      /**
       * 处理复制错误
       */
      handleCopyError(message) {
        this.showMessage(message, APP_CONSTANTS.MESSAGE_TYPES.WARNING);
      },
      
      // ======================
      // 拖拽相关方法
      // ======================
      
      /**
       * 拖拽开始
       */
      onDragStart(event) {
        this.isDragging = true;
        console.log('拖拽开始:', event);
      },
      
      /**
       * 拖拽结束
       */
      onDragEnd(event) {
        this.isDragging = false;
        console.log('拖拽结束:', event);
        // 拖拽结束后自动保存
        if (event.oldIndex !== event.newIndex) {
          this.save();
        }
      },
    }
  });

  initApp(app);
</script>
</html>